from django.shortcuts import render

# Create your views here.
from django.views import View
from django.http import JsonResponse

from users.models import User
from carts.utils import CartHelper

import json
import re

from django_redis import get_redis_connection


# GET /usernames/(?P<username>[a-zA-Z0-9_-]{5,20})/count/
class UsernameCountView(View):
    def get(self, request,username):
        try:
            count = User.objects.filter(username=username).count()
        except Exception as e:
            return JsonResponse({
                'code':400,
                'message':'操作数据库失败'
            })
        return JsonResponse({
            'code': 0,
            'message': 'OK',
            'count': count
        })


# POST /register/


class RegisterView(View):
    def post(self, request):
        """注册用户信息保存"""
        # ① 获取参数并进行校验
        req_data = json.loads(request.body.decode())
        username = req_data.get('username')
        password = req_data.get('password')
        password2 = req_data.get('password2')
        mobile = req_data.get('mobile')
        allow = req_data.get('allow')
        sms_code = req_data.get('sms_code')


        if not all([username, password, password2, mobile, allow, sms_code]):
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return JsonResponse({'code': 400,
                                 'message': 'username格式错误'})

        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'code': 400,
                                 'message': 'password格式错误'})

        if password != password2:
            return JsonResponse({'code': 400,
                                 'message': '两次密码不一致'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400,
                                 'message': '手机号格式错误'})

        # 短信验证码检验
        redis_conn = get_redis_connection('verify_code')
        sms_code_redis = redis_conn.get('sms_%s' % mobile)

        if not sms_code_redis:
            return JsonResponse({'code': 400,
                                 'message': '短信验证码过期'})

        if sms_code != sms_code_redis:
            return JsonResponse({'code': 400,
                                 'message': '短信验证码错误'})

        # ② 保存新增用户数据到数据库
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'message': '数据库保存错误'})

        from django.contrib.auth import login

        # 只要调用 login 方法，传入 request 和 user 对象
        # login 方法就会将 user 用户的信息存储到 session
        login(request, user)
        # ③ 返回响应
        response = JsonResponse({'code': 0,
                                 'message': 'OK'})

        # 设置 cookie 保存 username 用户名
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        cart_helper = CartHelper(request, response)
        cart_helper.merge_cookie_cart_to_redis()

        return response


from django.middleware.csrf import get_token

# GET /csrf_token/
class CSRFTokenView(View):
    def get(self, request):
        """获取csrf_token的值"""
        # ① 生成csrf_token的值
        csrf_token = get_token(request)

        # ② 将csrf_token的值返回
        return JsonResponse({'code': 0,
                             'message': 'OK',
                             'csrf_token': csrf_token})


from django.contrib.auth import authenticate, login

# POST /login/


class LoginView(View):
    def post(self, request):
        """用户登录"""
        # ① 获取参数并进行校验(参数完整性、用户名密码是否正确)
        req_data = json.loads(request.body.decode())


        username = req_data.get('username')
        password = req_data.get('password')
        remember = req_data.get('remember')

        if not all([username, password]):
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        # 判断客户端传递的 username 参数是否符合手机号格式
        import re
        if re.match(r'^1[3-9]\d{9}$', username):
            User.USERNAME_FIELD = 'mobile'

        # 账户和密码是否正确
        user = authenticate(username=username, password=password)

        if user is None:
            return JsonResponse({'code': 400,
                                 'message': '用户名或密码错误'})

        # ② 保存登录用户的状态信息
        login(request, user)

        if not remember:
            # 如果未选择记住登录，浏览器关闭即失效
            request.session.set_expiry(0)

        # ③ 返回响应，登录成功
        response = JsonResponse({'code': 0,
                                 'message': 'OK'})

        # 设置 cookie 保存 username 用户名
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        cart_helper = CartHelper(request, response)
        cart_helper.merge_cookie_cart_to_redis()

        return response


from django.contrib.auth import logout

# DELETE /logout/


class LogoutView(View):
    def delete(self, request):
        """退出登录"""
        # ① 请求登录用户的session信息
        logout(request)

        # ② 删除cookie中的username
        response = JsonResponse({'code': 0,
                                 'message': 'ok'})

        response.delete_cookie('username')

        # ③ 返回响应
        return response


from meiduo_mall.mixins import LoginRequiredMixin

# GET /user/


class UserInfoView(LoginRequiredMixin, View):
    def get(self, request):
        if not request.user.is_authenticated:
            return JsonResponse({'code': 400,
                                 'message': '用户未登录!'})

        """获取登录用户个人信息"""
        # ① 获取登录用户对象
        user = request.user

        # ② 返回响应数据
        info = {
            'username': user.username,
            'mobile': user.mobile,
            'email': user.email,
            'email_active': user.email_active
        }

        return JsonResponse({'code': 0,
                             'message': 'OK',
                             'user': info})



# PUT /user/email

class UserEmailView(LoginRequiredMixin, View):
    def put(self, request):
        """设置用户的个人邮箱"""
        # ① 获取参数并进行校验
        req_data = json.loads(request.body.decode())

        email = req_data.get('email')

        if not email:
            return JsonResponse({'code': 400,
                                 'message': '缺少email参数'})

        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return JsonResponse({'code': 400,
                                 'message': '参数email有误'})

        # ② 保存用户的个人邮箱设置
        user = request.user
        try:
            user.email = email
            user.save()
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'message': '邮箱设置失败'})

        from celery_tasks.email.tasks import send_verify_email
        verify_url = 'http://邮件验证链接地址'
        # 发出邮件发送的任务消息
        send_verify_email.delay(email, verify_url)

        # ③ 返回响应
        return JsonResponse({'code': 0,
                             'message': 'OK'})


from users.models import Address


# POST /addresses/
class AddressView(LoginRequiredMixin, View):
    def post(self, request):
        """用户收货地址新增"""
        # ① 判断当前用户的收货地址是否超过上限
        try:
            count = Address.objects.filter(user=request.user, is_delete=False).count()
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '获取地址数据出错'})

        if count >= 20:
            return JsonResponse({'code': 400,
                                 'message': '收货地址超过上限'})

        # ② 接收参数并进行数据校验
        req_data = json.loads(request.body.decode())
        title = req_data.get('title')
        receiver = req_data.get('receiver')
        province_id = req_data.get('province_id')
        city_id = req_data.get('city_id')
        district_id = req_data.get('district_id')
        place = req_data.get('place')
        mobile = req_data.get('mobile')
        phone = req_data.get('phone')
        email = req_data.get('email')

        if not all([title, receiver, province_id, city_id, district_id, place, mobile]):
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400,
                                 'message': '参数mobile有误'})

        if phone:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', phone):
                return JsonResponse({'code': 400,
                                     'message': '参数phone有误'})
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return JsonResponse({'code': 400,
                                     'message': '参数email有误'})

        # ③ 保存收货地址数据
        try:
            address = Address.objects.create(user=request.user, **req_data)

            # 设置默认收货地址
            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '新增地址保存失败'})

        # ④ 返回响应
        address_data = {
            'id': address.id,
            'title': address.title,
            'receiver': address.receiver,
            'province': address.province.name,
            'city': address.city.name,
            'district': address.district.name,
            'place': address.place,
            'mobile': address.mobile,
            'phone': address.phone,
            'email': address.email
        }
        return JsonResponse({'code': 0,
                             'message': 'OK',
                             'address': address_data})





